/*
 * FaceCat图形通讯框架
 * 著作权编号:2015SR229355+2020SR0266727
 * 上海卷卷猫信息技术有限公司
 */

#ifdef __FCPAINT_H__
#else                                                                            
#define __FCPAINT_H__

#include "../../stdafx.h"

namespace FaceCat{
template <class numtype>
   /*
    * 自定义集合
    */
   class ArrayList{
   public:
       /*
        * 数组
        */
       numtype *m_ary;
       /*
        * 大小
        */
       int m_size;
       /*
        * 容量
        */
       int m_capacity;
       /*
        * 模式
        */
       int m_mode;
       /*
        * 增长步长
        */
       int m_step;
   public:
       /*
        * 构造函数
        */
       ArrayList(){
           m_size = 0;
           m_ary = 0;
           m_capacity = 4;
           m_step = 4;
           m_mode = 0;
       }

       /*
        * 构造函数
        * @param capacity 容量
        */
       ArrayList(int capacity){
           m_size = 0;
           m_ary = 0;
           m_capacity = capacity;
           m_step = 4;
           m_mode = 0;
       }

       /*
        * 添加
        * @param value 数据
        */
       void add(numtype value){
           m_size += 1;
           if(!m_ary){
               if(m_mode == 0){
                   m_ary = new numtype[m_capacity];
               }
               else{
                   m_ary = (numtype*)malloc(sizeof(numtype) * m_capacity);
               }
           }
           else
           {
               if(m_size > m_capacity){
                   if(m_mode == 0){
                       m_capacity = (int)(m_size * 1.5);
                       numtype *newAry = new numtype[m_capacity];
                       for(int i = 0;i < m_size - 1; i++){
                           newAry[i] = m_ary[i];
                       }
                       delete[] m_ary;
                       m_ary = newAry;
                   }
                   else{
                       m_capacity += m_step;
                       m_ary = (numtype*)realloc(m_ary, sizeof(numtype) * m_capacity);
                   }
               }
           }
           m_ary[m_size - 1] = value;
       }

       /*
        * 批量添加
        * @param ary 数据
        * @param size 大小
        */
       void addranges(numtype *ary, int size){
           m_ary = ary;
           m_size = size;
           m_capacity = m_size;
           m_step = 4;
       }

       /*
        * 获取容量
        */
       int capacity(){
           return m_capacity;
       }

       /*
        * 清除
        */
       void clear(){
           if(m_ary){
               if(m_mode == 0){
                   delete[] m_ary;
               }
               else{
                   free(m_ary);
               }
               m_ary = 0;
           }
           m_size = 0;
       }

       /*
        * 获取数据
        */
       numtype get(int index){
           return m_ary[index];
       }

       /*
        * 插入数据
        * @param index 索引
        * @param value 数据
        */
       void insert(int index,numtype value){
           m_size += 1;
           if(!m_ary){
               if(m_mode == 0){
                   m_ary = new numtype[m_capacity];
               }
               else{
                   m_ary = (numtype*)malloc(sizeof(numtype) * m_capacity);
               }
           }
           else{
               bool build = false;
               if(m_size > m_capacity){
                   if(m_mode == 0){
                       m_capacity = (int)(m_size * 1.5);
                       numtype *newAry = new numtype[m_capacity];
                       for(int i = 0;i < m_size - 1;i++){
                           if(i < index){
                               newAry[i] = m_ary[i];
                           }
                           else if( i >= index){
                               newAry[i + 1] = m_ary[i];
                           }
                       }
                       delete[] m_ary;
                       m_ary = newAry;
                       build = true;
                   }
                   else{
                       m_capacity += m_step;
                       m_ary = (numtype*)realloc(m_ary, sizeof(numtype) * m_capacity);
                   }
               }
               if(!build)
               {
                   numtype last;
                   for(int i = index; i < m_size; i++){
                       if(i == index){
                           last = m_ary[i];
                       }
                       else if(i > index){
                           numtype temp = m_ary[i];
                           m_ary[i] = last;
                           last = temp;
                       }
                   }
               }
           }
           m_ary[index] = value;
       }

       /*
        * 移除数据
        * @param index 索引
        */
       void removeAt(int index){
           m_size -= 1;
           for(int i = index;i < m_size; i++){
               m_ary[i] = m_ary[i + 1];
           }
           bool reduce = false;
           if(m_mode == 0){
               if(m_capacity > 4 && m_size > 0){
                   if(m_capacity > (int)(m_size * 1.5)){
                       m_capacity = (int)(m_size * 1.5);
                       reduce = true;
                   }
               }
           }
           else{
               if(m_capacity - m_size > m_step){
                   m_capacity -= m_step;
                   reduce = true;
               }
           }
           if(reduce){
               if(m_capacity > 0){
                   if(m_mode == 0){
                       numtype *newAry = new numtype[m_capacity];
                       for(int i = 0;i < m_size; i++){
                           newAry[i] = m_ary[i];
                       }
                       delete[] m_ary;
                       m_ary = newAry;
                   }
                   else{
                       m_ary = (numtype*)realloc(m_ary, sizeof(numtype) * m_capacity);
                   }
               }
               else{
                   if(m_ary){
                       if(m_mode == 0){
                           delete[] m_ary;
                       }
                       else{
                           free(m_ary);
                       }
                       m_ary = 0;
                   }
               }
           }
       }

       /*
        * 设置数据
        * @param index 索引
        * @param value 值
        */
       void set(int index,numtype value){
           m_ary[index] = value;
       }

       /*
        * 设置容量
        * @param capacity 容量
        */
       void setCapacity(int capacity){
           m_capacity = capacity;
           if(m_ary){
               if(m_mode == 0){
                   numtype *newAry = new numtype[m_capacity];
                   for(int i = 0; i < m_size - 1; i++){
                       newAry[i] = m_ary[i];
                   }
                   delete[] m_ary;
                   m_ary = newAry;
               }
               else{
                   m_ary = (numtype*)realloc(m_ary, sizeof(numtype) * m_capacity);
               }
           }
       }

       /*
        * 设置步长
        * @param step 步长
        */
       void setStep(int step){
           m_step = step;
       }

       /*
        * 获取尺寸
        * @param step 尺寸
        */
       int size(){
           return m_size;
       }

       /*
        * 析构函数
        */
       virtual ~ArrayList(){
           clear();
       }

       /*
        * 拷贝构造函数
        */
       ArrayList(const ArrayList& rhs){
           if (this != &rhs) {
               m_size = rhs.m_size;
               m_capacity = rhs.m_capacity;
               m_mode = rhs.m_mode;
               m_step = rhs.m_step;
               if(m_mode == 0){
                   m_ary = new numtype[m_capacity];
               }
               else{
                   m_ary = (numtype*)malloc(sizeof(numtype) * m_capacity);
               }
               for (int i = 0; i < m_size; i++){
                   m_ary[i] = rhs.m_ary[i];
               }
           }
       }

       /*
        * 拷贝函数
        */
       const ArrayList& operator=(const ArrayList& rhs){
           if (this != &rhs) {
               clear();
               m_size = rhs.m_size;
               m_capacity = rhs.m_capacity;
               m_mode = rhs.m_mode;
               m_step = rhs.m_step;
               if(m_mode == 0){
                   m_ary = new numtype[m_capacity];
               }
               else{
                   m_ary = (numtype*)malloc(sizeof(numtype) * m_capacity);
               }
               for (int i = 0; i < m_size; i++){
                   m_ary[i] = rhs.m_ary[i];
               }
           }
           return *this;
       }
   };

   /*
    * 红黑树节点
    */
   template <typename KEY, typename VALUE>
   struct RBNode
   {
       int color;    //颜色 0:红 1:黑
       KEY key;    //关键字
       VALUE value; //值
       RBNode* left;    //左节点
       RBNode* right;    //右节点
       RBNode* parent;    //父节点
   };

   /*
    * 自定义哈希表
    */
   template<typename KEY, typename VALUE>
   class HashMap
   {
   private:
       RBNode<KEY, VALUE>* root;    //节点
       RBNode<KEY, VALUE>* nNode;    //外部结点，表示空节点，黑色的
       ArrayList<KEY> m_keys; //键的列表
       ArrayList<VALUE> m_values; //值的列表
   public:
       /*
        * 清除
        */
       void clear(){
           m_keys.clear();
           m_values.clear();
           destroy(root);
           root = nNode;
       }
       /*
        * 构造函数
        */
       HashMap(){
           nNode = buyNode();
           root = nNode;
           nNode->color = 1;
       }
       /*
        * 析构函数
        */
       ~HashMap(){
           m_keys.clear();
           m_values.clear();
           destroy(root);
           delete nNode;
           nNode = 0;
           root = 0;
       }
   protected:
       /*
        * 插入
        */
       bool insert(const KEY &key, VALUE value){
           RBNode<KEY, VALUE>* pr = nNode;
           RBNode<KEY, VALUE>* s = root;
           while (s != nNode){
               if (key == s->key){
                   return false;
               }
               pr = s;
               if (key < s->key){
                   s = s->left;
               }
               else{
                   s = s->right;
               }
           }
           s = buyNode(key);
           if (pr == nNode){
               root = s;
               root->parent = pr;
           }
           else{
               if (key < pr->key){
                   pr->left = s;
               }
               else{
                   pr->right = s;
               }
               s->parent = pr;
           }
           insertFixup(s);
           s->value = value;
           return true;
       }
       /*
        * 删除节点
        */
       bool removeKey(KEY key){
           RBNode<KEY, VALUE>* t;
           if ((t = search(root, key)) != nNode){
               removeKey(t);
               return true;
           }
           return false;
       }
       /*
        * 申请结点结点，将结点的颜色初始化为红色，初始化结点的关键字，其他的初始化为空
        */
       RBNode<KEY, VALUE>* buyNode(const KEY &x = KEY()){
           RBNode<KEY, VALUE>* s = new RBNode<KEY, VALUE>();
           s->color = 0;
           s->left = s->right = s->parent = nNode;
           s->key = x;
           return s;
       }
       /*
        * 左转，对z结点左转
        */
       void leftRotate(RBNode<KEY, VALUE>* z){
           RBNode<KEY, VALUE>* y = z->right;
           z->right = y->left;
           if (y->left != nNode){
               y->left->parent = z;
           }
           y->parent = z->parent;
           if (root == z){
               root = y;
           }
           else if (z == z->parent->left){
               z->parent->left = y;
           }
           else{
               z->parent->right = y;
           }
           y->left = z;
           z->parent = y;
       }
       /*
        * 右转，对z结点进行右转
        */
       void rightRotate(RBNode<KEY, VALUE>* z){
           RBNode<KEY, VALUE>* y = z->left;
           z->left = y->right;
           if (y->right != nNode){
               y->right->parent = z;
           }
           y->parent = z->parent;
           if (root == z){
               root = y;
           }
           else if (z == z->parent->left){
               z->parent->left = y;
           }
           else{
               z->parent->right = y;
           }
           y->right = z;
           z->parent = y;
       }
       /*
        * 插入后的调整函数
        */
       void insertFixup(RBNode<KEY, VALUE>* s){
           RBNode<KEY, VALUE>* uncle;
           while (s->parent->color == 0){
               if (s->parent == s->parent->parent->left){
                   uncle = s->parent->parent->right;
                   if(uncle){
                       if (uncle->color == 0){
                           s->parent->color = 1;
                           uncle->color = 1;
                           s->parent->parent->color = 0;
                           s = s->parent->parent;
                       }else{
                           if (s == s->parent->right){
                               s = s->parent;
                               leftRotate(s);
                           }
                           s->parent->color = 1;
                           s->parent->parent->color = 0;
                           rightRotate(s->parent->parent);
                       }
                   }else{
                       break;
                   }
               }else{
                   if (s->parent == s->parent->parent->right){
                       uncle = s->parent->parent->left;
                       if(uncle){
                           if (uncle->color == 0){
                               s->parent->color = 1;
                               uncle->color = 1;
                               s->parent->parent->color = 0;
                               s = s->parent->parent;
                           }else{
                               if (s == s->parent->left){
                                   s = s->parent;
                                   rightRotate(s);
                               }
                               s->parent->color = 1;
                               s->parent->parent->color = 0;
                               leftRotate(s->parent->parent);
                           }
                       }else{
                           break;
                       }
                   }
               }
           }
           root->color = 1;
       }
       RBNode<KEY, VALUE>* search(RBNode<KEY, VALUE>* rt, KEY key) const{
           if (rt == nNode){
               return nNode;
           }
           if (rt->key == key){
               return rt;
           }
           if (key < rt->key){
               return search(rt->left, key);
           }else{
               return search(rt->right, key);
           }
       }
       /*
        * 将u的子节点指针指向u改变指向v，将v的父节点改变为指向u的父节点
        */
       void transplant(RBNode<KEY, VALUE>* u, RBNode<KEY, VALUE>* v){
           if (u->parent == nNode){
               root = v;
           }else if (u == u->parent->left){
               u->parent->left = v;
           }else{
               u->parent->right = v;
           }
           v->parent = u->parent;
       }
       /*
        * 找到最左结点(最小)
        */
       RBNode<KEY, VALUE>* minimum(RBNode<KEY, VALUE>* x){
           if (x->left == nNode){
               return x;
           }
           return minimum(x->left);
       }
       /*
        * 删除红黑树结点z
        */
       void removeKey(RBNode<KEY, VALUE>* z){
           RBNode<KEY, VALUE>* x = nNode;
           RBNode<KEY, VALUE>* y = z;
           int ycolor = y->color;
           if (z->left == nNode){
               x = z->right;
               transplant(z, z->right);
           }
           else if (z->right == nNode){
               x = z->left;
               transplant(z, z->left);
           }else{
               y = minimum(z->right);
               ycolor = y->color;
               x = y->right;
               if (y->parent == z){
                   x->parent = y;
               }else{
                   transplant(y, y->right);
                   y->right = z->right;
                   y->right->parent = y;
               }
               transplant(z, y);
               y->left = z->left;
               z->left->parent = y;
               y->color = z->color;
           }
           if (ycolor == 1){
               removeFixup(x);
           }
       }
       /*
        * 红黑树删除调整
        */
       void removeFixup(RBNode<KEY, VALUE>* x){
           while (x != root && x->color == 1){
               if (x == x->parent->left){
                   RBNode<KEY, VALUE>* w = x->parent->right;
                   if (w->color == 0){
                       w->color = 1;
                       x->parent->color = 0;
                       leftRotate(x->parent);
                       w = x->parent->right;
                   }
                   if (w->left->color == 1 && w->right->color == 1){
                       w->color = 0;
                       x = x->parent;
                   }else{
                       if (w->right->color == 1){
                           w->color = 0;
                           w->left->color = 1;
                           rightRotate(w);
                           w = x->parent->right;
                       }
                       w->color = w->parent->color;
                       w->parent->color = 1;
                       w->right->color = 1;
                       leftRotate(x->parent);
                       x = root;
                   }
               }else{
                   RBNode<KEY, VALUE>* w = x->parent->left;
                   if (w->color == 0){
                       w->parent->color = 0;
                       w->color = 1;
                       rightRotate(x->parent);
                       w = x->parent->left;
                   }
                   if (w->right->color == 1 && w->right->color == 1){
                       w->color = 0;
                       x = x->parent;
                   }else{
                       if (w->left->color == 1){
                           w->right->color = 1;
                           w->color = 0;
                           leftRotate(w);
                           w = x->parent->left;
                       }
                       w->color = x->parent->color;
                       x->parent->color = 1;
                       w->left->color = 1;
                       rightRotate(x->parent);
                       x = root;
                   }
               }
           }
           x->color = 1;
       }
       /*
        * 销毁红黑树
        */
       void destroy(RBNode<KEY, VALUE>* &rt){
           if (rt == nNode){
               return;
           }
           if (rt->left != nNode){
               destroy(rt->left);
           }
           if (rt->right != nNode){
               destroy(rt->right);
           }
           delete rt;
           rt = 0;
       }
   public:
       /*
        * 插入数据
        * key 键
        * value 值
        */
       void put(KEY key, VALUE value){
           RBNode<KEY, VALUE>* t;
           if ((t = search(root, key)) != nNode){
               t->value = value;
               int size = m_keys.size();
               if(size > 0){
                   for(int i = 0; i < size; i++){
                       if(m_keys.get(i) == key){
                           m_values.set(i, value);
                           break;
                       }
                   }
               }
           }else{
               insert(key, value);
               m_keys.add(key);
               m_values.add(value);
           }
       }
       /*
        * 是否包含键
        * key 键
        */
       bool containsKey(KEY key){
           RBNode<KEY, VALUE>* t;
           if ((t = search(root, key)) != nNode){
               return true;
           }
           return false;
       }
       /*
        * 根据索引获取键
        * index 索引
        */
       KEY getKey(int index){
           return m_keys.get(index);
       }
       /*
        * 根据索引获取值
        * index 索引
        */
       VALUE getValue(int index){
           return m_values.get(index);
       }
       /*
        * 根据键获取值
        * key 键
        */
       VALUE get(KEY key){
           RBNode<KEY, VALUE>* t;
           if ((t = search(root, key)) != nNode){
               return t->value;
           }
           return 0;
       }
       /*
        * 根据键尝试获取值
        * key 键
        * value 值
        */
       bool tryget(KEY key, VALUE *value){
           RBNode<KEY, VALUE>* t;
           if ((t = search(root, key)) != nNode){
               *value = t->value;
               return true;
           }
           return false;
       }
       /*
        * 移除
        * key 键
        */
       void remove(KEY key){
           if(removeKey(key)){
               int size = m_keys.size();
               if(size > 0){
                   for(int i = 0; i < size; i++){
                       if(m_keys.get(i) == key){
                           m_keys.removeAt(i);
                           m_values.removeAt(i);
                           break;
                       }
                   }
               }
           }
       }
       /*
        * 获取尺寸
        */
       int size(){
           return m_keys.size();
       }
       /*
        * 拷贝构造函数
        */
       HashMap(const HashMap& rhs){
           nNode = buyNode();
           root = nNode;
           nNode->color = 1;
           if (this != &rhs) {
               m_keys = rhs.m_keys;
               m_values = rhs.m_values;
               for(int i = 0; i < m_keys.size(); i++){
                   insert(m_keys.get(i), m_values.get(i));
               }
           }
       }
       /*
        * 重写等于方法
        */
       const HashMap& operator=(const HashMap& rhs){
           if (this != &rhs) {
               clear();
               m_keys = rhs.m_keys;
               m_values = rhs.m_values;
               for(int i = 0; i < m_keys.size(); i++){
                   insert(m_keys.get(i), m_values.get(i));
               }
           }
           return *this;
       }
   };

   /*
    * 坐标点
    */
   struct FCPoint{
       /**
        * 创建浮点
        */
   public:
       int x;
       int y;
   };

   /*
    * 坐标点
    */
   struct FCPointF{
       /**
        * 创建浮点
        */
   public:
       float x;
       float y;
   };

   /*
    * 尺寸
    */
   struct FCSize{
       /**
        * 创建浮点型尺寸
        */
   public:
       int cx;
       int cy;
   };

   /*
    * 尺寸
    */
   struct FCSizeF{
       /**
        * 创建浮点型尺寸
        */
   public:
       float cx;
       float cy;
   };

   /*
    * 矩形
    */
   struct FCRect{
       /**
        * 创建矩形
        */
   public:
       /**
        * 左侧坐标
        */
       int left;
       /**
        * 顶部坐标
        */
       int top;
       /**
        * 右侧坐标
        */
       int right;
       /**
        * 底部坐标
        */
       int bottom;
   };

   /*
    * 矩形
    */
   struct FCRectF{
       /**
        * 创建矩形
        */
   public:
       /**
        * 左侧坐标
        */
       float left;
       /**
        * 顶部坐标
        */
       float top;
       /**
        * 右侧坐标
        */
       float right;
       /**
        * 底部坐标
        */
       float bottom;
   };

    struct FCAnchor{
	public:
	    /**
		 * 底部坐标
		 */
		bool bottom;
		/**
		 * 左侧坐标
		 */
		bool left;
		/**
		 * 右侧坐标
		 */
		bool right;
		/**
		 * 顶部左标
		 */
		bool top;
	    /**
         * 创建锚定信息
        */
		FCAnchor(){
			bottom = false;
			left = false;
			right = false;
			top = false;
		}
		/**
         * 创建锚定信息
         * @param left  左侧
         * @param top   顶部
         * @param right 右侧
         * @param bottom    底部
        */
		FCAnchor(bool left, bool top, bool right, bool bottom){
			this->left = left;
			this->top = top;
			this->right = right;
			this->bottom = bottom;
		}
	};

	/*
	* 视图内容的布局
	*/
    enum FCContentAlignment{
        FCContentAlignment_BottomCenter, //中部靠下居中对齐
        FCContentAlignment_BottomLeft, //左下方对齐
        FCContentAlignment_BottomRight, //右下方对齐
        FCContentAlignment_MiddleCenter, //垂直居中
        FCContentAlignment_MiddleLeft, //垂直居中靠左
        FCContentAlignment_MiddleRight, //垂直居中靠右
        FCContentAlignment_TopCenter, //中部靠上居中对齐
        FCContentAlignment_TopLeft, //左上方对齐
        FCContentAlignment_TopRight //右上方对齐
	};

	/*
	* 光标
	*/
    enum FCCursors{
		FCCursors_AppStarting, //程序启动
        FCCursors_Arrow, //箭头
        FCCursors_Cross, //十字线
        FCCursors_Hand, //手型
		FCCursors_Help, //帮助
		FCCursors_IBeam, //文本光标出现
		FCCursors_No, //当前操作无效
        FCCursors_SizeAll, //四个箭头
        FCCursors_SizeNESW, //对角线大小调整光标
        FCCursors_SizeNS, //双向垂直大小调整光标
        FCCursors_SizeNWSE, //双向对角线大小调整光标
        FCCursors_SizeWE, //双向水平大小调整光标
		FCCursors_UpArrow, //向上箭头
		FCCursors_WaitCursor //等待
	};

	/*
	* 视图绑定边缘类型
	*/
    enum FCDockStyle{
		FCDockStyle_Bottom, //底部
		FCDockStyle_Fill, //填充
		FCDockStyle_Left, //左侧
		FCDockStyle_None, //不绑定
		FCDockStyle_Right, //右侧
		FCDockStyle_Top //顶部
	};

	/*
	* 视图横向排列方式
	*/
    enum FCHorizontalAlign{
		FCHorizontalAlign_Center, //居中
		FCHorizontalAlign_Right, //远离
		FCHorizontalAlign_Inherit, //继承
		FCHorizontalAlign_Left //靠近
	};

	/*
	* 视图纵向排列方式
	*/
    enum FCVerticalAlign{
		FCVerticalAlign_Bottom, //底部
		FCVerticalAlign_Inherit, //中间
		FCVerticalAlign_Middle, //继承
		FCVerticalAlign_Top //顶部
	};

	/*
	* 视图布局样式
	*/
    enum FCLayoutStyle{
		FCLayoutStyle_BottomToTop, //自下而上
		FCLayoutStyle_LeftToRight, //从左向右
		FCLayoutStyle_None, //无布局
		FCLayoutStyle_RightToLeft, //从右向左
		FCLayoutStyle_TopToBottom //自上而下
	};

    /**
	* 背景色
	*/
	#define FCColor_Back (Long)-200000000001
	/**
	* 边线颜色
	*/
	#define FCColor_Border (Long)-200000000002
	/**
	* 前景色
    */
	#define FCColor_Text (Long)-200000000003
	/**
	* 不可用的背景色
	*/
    #define FCColor_DisabledBack (Long)-200000000004
    /**
	* 不可用的前景色
	*/
    #define FCColor_DisabledText (Long)-200000000005
    /**
	 * 触摸悬停的背景色
	 */
	#define FCColor_Hovered (Long)-200000000006
	/**
	 * 触摸被按下的背景色
	 */
	#define FCColor_Pushed (Long)-200000000007
	/**
	* 空颜色
	*/
	#define FCColor_None (Long)-200000000000

	class FCPaint;

	/*
	* 颜色表示
	*/
    class FCColor{
	public:
		/**
         * @returns RGB颜色
        */
		static Long rgb(int r, int g, int b);
	    /**
         * @returns RGBA颜色
        */
		static Long rgba(int r, int g, int b, int a);
	    /**
         * 获取RGB颜色
        */
		static void toRgba(FCPaint *paint, Long dwPenColor, int *r, int *g, int *b, int *a);
	    /**
         * 获取比例色
         * @param originalColor  原始色
         * @param ratio  比例
        */
		static Long ratioColor(FCPaint *paint, Long originalColor, double ratio);
		/**
		 * 获取反色
		 */
		static Long reverse(FCPaint *paint, Long originalColor);
	};

	/*
	* 字体
	*/
    class FCFont{
	public:
	    /**
		 * 字体
		 */
		String m_fontFamily;
		/**
		 * 字体大小
		 */
		float m_fontSize;
		/**
		 * 是否粗体
		 */
		bool m_bold;
		/**
		 * 是否有下划线
		 */
		bool m_underline;
		/**
		 * 是否斜体
		 */
		bool m_italic;
		/**
		 * 是否有删除线
		 */
		bool m_strikeout;
		/*
		* 旋转角度
		*/
		bool m_angle;
		/*
		* 创建字体
		*/
		FCFont(){
			m_fontFamily = L"Default";
			m_fontSize = 12;
			m_bold = false;
			m_underline = false;
			m_italic = false;
			m_strikeout = false;
			m_angle = 0;
		}
		/**
         * 创建字体
         * @param  fontFamily 字体
         * @param fontSize  字号
        */
		FCFont(const String& fontFamily, float fontSize){
			m_fontFamily = fontFamily;
			m_fontSize = fontSize;
			m_bold = false;
			m_underline = false;
			m_italic = false;
			m_strikeout = false;
			m_angle = 0;
		}
	    /**
         * 创建字体
         * @param  fontFamily 字体
         * @param fontSize  字号
         * @param bold 是否粗体
         * @param underline 是否有下划线
         * @param italic 是否斜体
         * @param strikeout 是否有删除线
        */
		FCFont(const String& fontFamily, float fontSize, bool bold, bool underline, bool italic){
			m_fontFamily = fontFamily;
			m_fontSize = fontSize;
			m_bold = bold;
			m_underline = underline;
			m_italic = italic;
			m_strikeout = false;
			m_angle = 0;
		}
	    /**
         * 创建字体
         * @param  fontFamily 字体
         * @param fontSize  字号
         * @param bold 是否粗体
         * @param underline 是否有下划线
         * @param italic 是否斜体
         * @param strikeout 是否有删除线
        */
		FCFont(const String& fontFamily, float fontSize, bool bold, bool underline, bool italic, bool strikeout){
			m_fontFamily = fontFamily;
			m_fontSize = fontSize;
			m_bold = bold;
			m_underline = underline;
			m_italic = italic;
			m_strikeout = strikeout;
			m_angle = 0;
		}
	public:
		/*
		* 拷贝字体
		*/
		void copy(FCFont *font){
			m_fontFamily = font->m_fontFamily;
			m_fontSize = font->m_fontSize;
			m_bold = font->m_bold;
			m_underline = font->m_underline;
			m_italic = font->m_italic;
			m_strikeout = font->m_strikeout;
			m_angle = font->m_angle;
		}
	};

	/*
	* 边距
	*/
    struct FCPadding{
	public:
	    /**
		 * 底边距
		 */
		int bottom;
		/**
		 * 左边距
		 */
		int left;
		/**
		 * 右边距
		 */
		int right;
		/**
		 * 顶边距
		 */
		int top;
		/**
		 * 创建边距
		 */
		FCPadding(){
			bottom = 0;
			left = 0;
			right = 0;
			top = 0;
		}
		/**
		 * 创建边距
		 */
		FCPadding(int all){
			bottom = all;
			left = all;
			right = all;
			top = all;
		}	
		/**
		 * 创建边距
		 */
		FCPadding(int left, int top, int right, int bottom){
			this->left = left;
			this->top = top;
			this->right = right;
			this->bottom = bottom;
		}
	};

	/*
	* 触摸信息
	*/
    class FCTouchInfo{
    public:
		/*
		* 鼠标按钮
		*/
		int m_buttons;
		/*
		* 点击次数
		*/
        int m_clicks;
        /**
		 * 滚动值
		 */
        int m_delta;
        /**
		 * 是否第一个坐标
		 */
        bool m_firstTouch;
        /**
		 * 第一个坐标
		 */
        FCPoint m_firstPoint;
        /**
		 * 是否第二个坐标
		 */
        bool m_secondTouch;
		/**
		 * 第二个坐标
		 */
        FCPoint m_secondPoint;
    public:
		/*
		* 构造函数
		*/
        FCTouchInfo(){
			m_buttons = 0;
            m_clicks = 0;
            m_delta = 0;
            m_firstTouch = false;
            m_firstPoint.x = 0;
            m_firstPoint.y = 0;
            m_secondTouch = false;
            m_secondPoint.x = 0;
            m_secondPoint.y = 0;
        }
		/*
		* 析构函数
		*/
        ~FCTouchInfo(){
        }
    };

	/*
	* 绘图
	*/
    class FCPaint{
	public:
		/*
		* 构造函数
		*/
		FCPaint();
		/*
		* 析构函数
		*/
		virtual ~FCPaint();
	public:
	    /**
         * 添加曲线
         * @param  rect 矩形区域
         * @param startAngle 从 x 轴到弧线的起始点沿顺时针方向度量的角（以度为单位）
         * @param sweepAngle 从 startAngle 参数到弧线的结束点沿顺时针方向度量的角（以度为单位）
        */
		virtual void addArc(const FCRect& rect, float startAngle, float sweepAngle);
	    /**
         * 添加贝赛尔曲线
         * @param  point1  坐标1
         * @param  point2  坐标2
         * @param  point3  坐标3
         * @param  point4  坐标4
        */
		virtual void addBezier(FCPoint *apt, int cpt);
	    /**
         * 添加曲线
         * @param  points  点阵
        */
		virtual void addCurve(FCPoint *apt, int cpt);
	    /**
         * 添加椭圆
         * @param  rect 矩形
        */
		virtual void addEllipse(const FCRect& rect);
	    /**
         * 添加直线
         * @param  x1 第一个点的横坐标
         * @param  y1 第一个点的纵坐标
         * @param  x2 第二个点的横坐标
         * @param  y2 第二个点的纵坐标
        */
		virtual void addLine(int x1, int y1, int x2, int y2);
	    /**
         * 添加矩形
         * @param  rect 区域
        */
		virtual void addRect(const FCRect& rect);
	    /**
         * 添加扇形
         * @param  rect 矩形区域
         * @param startAngle 从 x 轴到弧线的起始点沿顺时针方向度量的角（以度为单位）
         * @param sweepAngle 从 startAngle 参数到弧线的结束点沿顺时针方向度量的角（以度为单位）
        */
		virtual void addPie(const FCRect& rect, float startAngle, float sweepAngle);
		/**
         * 添加文字
         * @param  text 文字
         * @param  font 字体
         * @param  rect 区域
        */
		virtual void addText(String strText, FCFont *font, const FCRect& rect);
	    /**
         * 添加文字
         * @param  strText 文字
         * @param  font 字体
         * @param  rect 区域
        */
		virtual void addText(String strText, FCFont *font, const FCRect& rect, int width);
		/*
		* 开始导出
		*/
		virtual void beginExport(const String& exportPath, const FCRect& rect);
	    /**
         * 开始绘图
         * @param hdc  HDC
         * @param wRect 窗体区域
         * @param pRect 刷新区域
        */
        virtual void beginPaint(int hDC, const FCRect& wRect, const FCRect& pRect);
		/**
		 * 开始一段路径
		 */
		virtual void beginPath();
		/**
		 * 清除缓存
		 */
		virtual void clearCaches();
		/**
		 * 裁剪路径
		 */
		virtual void clipPath();
		/**
		 * 闭合路径
		 */
		virtual void closeFigure();
		/**
		 * 结束一段路径
		 */
		virtual void closePath();
	    /**
         * 绘制弧线
         * @param  dwPenColor 颜色
         * @param  width  宽度
         * @param  style  样式
         * @param  rect   矩形区域
         * @param  startAngle  从 x 轴到弧线的起始点沿顺时针方向度量的角（以度为单位）
         * @param sweepAngle   从 startAngle 参数到弧线的结束点沿顺时针方向度量的角（以度为单位）
        */
		virtual void drawArc(Long dwPenColor, float width, int style, const FCRect& rect, float startAngle, float sweepAngle);
	    /**
         * 设置贝赛尔曲线
         * @param  dwPenColor 颜色
         * @param  width  宽度
         * @param  style  样式
         * @param points  坐标阵
        */
		virtual void drawBezier(Long dwPenColor, float width, int style, FCPoint *apt, int cpt);
	    /**
         * 绘制曲线
         * @param  dwPenColor 颜色
         * @param  width  宽度
         * @param  style  样式
         * @param points  坐标阵
        */
		virtual void drawCurve(Long dwPenColor, float width, int style, FCPoint *apt, int cpt);
	    /**
         * 绘制椭圆
         * @param  dwPenColor 颜色
         * @param  width  宽度
         * @param  style  样式
         * @param  rect   矩形区域
        */
		virtual void drawEllipse(Long dwPenColor, float width, int style, const FCRect& rect);
	    /**
         * 绘制椭圆
         * @param  dwPenColor 颜色
         * @param  width  宽度
         * @param  style  样式
         * @param  left 左侧坐标
         * @param  top  顶部左标
         * @param  right 右侧坐标
         * @param  bottom  底部坐标
        */
		virtual void drawEllipse(Long dwPenColor, float width, int style, int left, int top, int right, int bottom);
	    /**
         * 绘制图片
         * @param  imagePath  图片路径
         * @param  rect   绘制区域
        */
		virtual void drawImage(String imagePath, const FCRect& rect);
	    /**
         * 绘制直线
         * @param  dwPenColor 颜色
         * @param  width  宽度
         * @param  style  样式
         * @param  x1 第一个点的横坐标
         * @param  y1 第一个点的纵坐标
         * @param  x2 第二个点的横坐标
         * @param  y2 第二个点的纵坐标
        */
		virtual void drawLine(Long dwPenColor, float width, int style, const FCPoint& x, const FCPoint& y);
	    /**
         * 绘制直线
         * @param  dwPenColor 颜色
         * @param  width  宽度
         * @param  style  样式
         * @param  x 第一个点坐标
         * @param  y 第二个点的坐标
        */
		virtual void drawLine(Long dwPenColor, float width, int style, int x1, int y1, int x2, int y2);
	    /**
         * 绘制路径
         * @param  dwPenColor 颜色
         * @param  width  宽度
         * @param  style  样式
        */
		virtual void drawPath(Long dwPenColor, float width, int style);
	    /**
         * 绘制弧线
         * @param  dwPenColor 颜色
         * @param  width  宽度
         * @param  style  样式
         * @param  rect   矩形区域
         * @param  startAngle  从 x 轴到弧线的起始点沿顺时针方向度量的角（以度为单位）
         * @param sweepAngle   从 startAngle 参数到弧线的结束点沿顺时针方向度量的角（以度为单位）
        */
		virtual void drawPie(Long dwPenColor, float width, int style, const FCRect& rect, float startAngle, float sweepAngle);
	    /**
         * 绘制多边形
         * @param  dwPenColor 颜色
         * @param  width  宽度
         * @param  style  样式
         * @param  apt  点的数组
		 * @param  cpt  长度
        */
		virtual void drawPolygon(Long dwPenColor, float width, int style, FCPoint *apt, int cpt);
	    /**
         * 绘制大量直线
         * @param  dwPenColor 颜色
         * @param  width  宽度
         * @param  style  样式
         * @param  apt  点的数组
		 * @param  cpt  长度
        */
		virtual void drawPolyline(Long dwPenColor, float width, int style, FCPoint *apt, int cpt);
	    /**
         * 绘制矩形
         * @param  dwPenColor 颜色
         * @param  width  宽度
         * @param  style  样式
		 * @param  left 左侧坐标
         * @param  top  顶部左标
         * @param  right 右侧坐标
         * @param  bottom  底部坐标
        */
		virtual void drawRect(Long dwPenColor, float width, int style, int left, int top, int right, int bottom);
	    /**
         * 绘制矩形
         * @param  dwPenColor 颜色
         * @param  width  宽度
         * @param  style  样式
         * @param  rect   矩形区域
        */
		virtual void drawRect(Long dwPenColor, float width, int style, const FCRect& rect);
	    /**
         * 绘制圆角矩形
         * @param  dwPenColor 颜色
         * @param  width  宽度
         * @param  style  样式
         * @param  rect   矩形区域
         * @param  cornerRadius 边角半径
        */
		virtual void drawRoundRect(Long dwPenColor, float width, int style, const FCRect& rect, int cornerRadius);
	    /**
         * 绘制矩形
         * @param  strText   文字
         * @param  dwPenColor 颜色
         * @param  font   字体
         * @param  rect   矩形区域
        */
		virtual void drawText(String strText, Long dwPenColor, FCFont *font, const FCRect& rect);
		/**
         * 绘制矩形
         * @param  strText   文字
         * @param  dwPenColor 颜色
         * @param  font   字体
         * @param  rect   矩形区域
        */
		virtual void drawText(String strText, Long dwPenColor, FCFont *font, const FCRect& rect, int width);
	    /**
         * 绘制矩形
         * @param  strText   文字
         * @param  dwPenColor 颜色
         * @param  font   字体
         * @param  rect   矩形区域
        */
		virtual void drawText(String strText, Long dwPenColor, FCFont *font, const FCRectF& rect);
		/**
         * 绘制矩形
         * @param  strText   文字
         * @param  dwPenColor 颜色
         * @param  font   字体
         * @param  rect   矩形区域
        */
		virtual void drawText(String strText, Long dwPenColor, FCFont *font, const FCRectF& rect, int width);
	    /**
         * 绘制自动省略结尾的文字
         * @param  strText   文字
         * @param  dwPenColor 颜色
         * @param  font   字体
         * @param  rect   矩形区域
        */
		virtual void drawTextAutoEllipsis(String strText, Long dwPenColor, FCFont *font, const FCRect& rect);
		/**
		 * 结束导出
		 */
		virtual void endExport();
		/**
		 * 结束绘图
		 */
		virtual void endPaint();
		/*
		* 去除裁剪路径
		*/
		virtual void excludeClipPath();
	    /**
         * 填充椭圆
         * @param  dwPenColor 颜色
         * @param  rect   矩形区域
        */
		virtual void fillEllipse(Long dwPenColor, const FCRect& rect);
	    /**
         * 绘制渐变椭圆
         * @param  dwFirst  开始颜色
         * @param  dwSecond 结束颜色
         * @param  rect     矩形
         * @param  angle    角度
        */
		virtual void fillGradientEllipse(Long dwFirst, Long dwSecond, const FCRect& rect, int angle);
		/*
		* 绘制渐变区域
		*/
		virtual void fillGradientPath(Long dwFirst, Long dwSecond, const FCRect& rect, int angle);
	    /**
         * 填充渐变路径
         * @param  dwFirst  开始颜色
         * @param  dwSecond 结束颜色
         * @param  apt  点的数组
		 * @param  cpt  长度
         * @param  angle    角度
        */
		virtual void fillGradientPolygon(Long dwFirst, Long dwSecond, FCPoint *apt, int cpt, int angle);
	    /**
         * 绘制渐变矩形
         * @param  dwFirst  开始颜色
         * @param  dwSecond 结束颜色
         * @param  rect     矩形
         * @param  cornerRadius     圆角半径
         * @param  angle    角度
        */
		virtual void fillGradientRect(Long dwFirst, Long dwSecond, const FCRect& rect, int cornerRadius, int angle);
	    /**
         * 填充路径
         * @param  dwPenColor 颜色
        */
		virtual void fillPath(Long dwPenColor);
	    /**
         * 绘制扇形
         * @param  dwPenColor 颜色
         * @param  rect   矩形区域
         * @param  startAngle  从 x 轴到弧线的起始点沿顺时针方向度量的角（以度为单位）
         * @param sweepAngle   从 startAngle 参数到弧线的结束点沿顺时针方向度量的角（以度为单位）
        */
		virtual void fillPie(Long dwPenColor, const FCRect& rect, float startAngle, float sweepAngle);
	    /**
         * 填充多边形
         * @param  dwPenColor 颜色
         * @param  apt  点的数组
		 * @param  cpt  长度
        */
		virtual void fillPolygon(Long dwPenColor, FCPoint *apt, int cpt);
	    /**
         * 填充矩形
         * @param  dwPenColor 颜色
         * @param  rect   矩形区域
        */
		virtual void fillRect(Long dwPenColor, const FCRect& rect);
	    /**
         * 填充矩形
         * @param  text   文字
         * @param  dwPenColor 颜色
         * @param  font   字体
		* @param  left 左侧坐标
         * @param  top  顶部左标
         * @param  right 右侧坐标
         * @param  bottom  底部坐标
        */
		virtual void fillRect(Long dwPenColor, int left, int top, int right, int bottom);
	    /**
         * 填充圆角矩形
         * @param  dwPenColor 颜色
         * @param  rect   矩形区域
         * @param  cornerRadius 边角半径
        */
		virtual void fillRoundRect(Long dwPenColor, const FCRect& rect, int cornerRadius);
	    /**
         * 获取颜色
         * @param  dwPenColor 输入颜色
         * @returns   输出颜色
        */
		virtual Long getColor(Long dwPenColor);
	    /**
         * 获取要绘制的颜色
         * @param  dwPenColor 输入颜色
         * @returns   输出颜色
        */
		virtual Long getPaintColor(Long dwPenColor);
		/**
		 * 获取偏移
		 */
		virtual FCPoint getOffset();
		/**
		* 获取缩放比例
		* @param scaleFactorX 横向缩放比例
		* @param scaleFactorY 纵向缩放比例
		*/
		virtual void getScaleFactor(double *scaleFactorX, double *scaleFactorY);
		/*
        * 旋转处理
        * @param angle 角度
        */
        virtual void rotate(float angle);
        /*
        * 缩放处理
        * @param sx 横向比例
        * @param sy 纵向比例
        */
        virtual void scale(float sx, float sy);
	    /**
         * 旋转角度
         * @param  op   圆心坐标
         * @param  mp   点的坐标
         * @param  angle  角度
         * @returns  结果坐标
        */
		virtual FCPoint rotate(const FCPoint& op, const FCPoint& mp, int angle);
	    /**
         * 设置裁剪区域
         * @param  rect   区域
        */
		virtual void setClip(const FCRect& rect);
		/*
        * 设置直线两端的样式
        * @param lineCap 样式
        */
        virtual void setLineCap(int lineCap);
        /*
        * 设置折线连接样式
        * @param lineCap 样式
        */
        virtual void setLineJoin(int lineJoin);
	    /**
         * 设置直线两端的样式
         * @param  startLineCap  开始的样式
         * @param  endLineCap  结束的样式
        */
		virtual void setLineCap(int startLineCap, int endLineCap);
	    /**
         * 设置偏移
         * @param  offset  偏移坐标
        */
		virtual void setOffset(const FCPoint& offset);
	    /**
         * 设置透明度
         * @param  opacity  透明度
        */
		virtual void setOpacity(float opacity);
	    /**
         * 设置资源的路径
         * @param  resourcePath  资源的路径
        */
        virtual void setResourcePath(const String& resourcePath);
        /**
         * 设置旋转角度
         * @param  rotateAngle  旋转角度
        */
		virtual void setRotateAngle(int rotateAngle);
	    /**
         * 设置缩放因子
         * @param  scaleFactorX   横向因子
         * @param  scaleFactorY   纵向因子
        */
		virtual void setScaleFactor(double scaleFactorX, double scaleFactorY);
	    /**
         * 设置是否支持透明色
         * @returns  是否支持
        */
		virtual bool supportTransparent();
		/**
         * 获取文字大小
         * @param  text   文字
         * @param  font   字体
		 * @param  width   字符最大宽度
         * @returns  字体大小
        */
		virtual FCSize textSize(String strText, FCFont *font);
	    /**
         * 获取文字大小
         * @param  text   文字
         * @param  font   字体
		 * @param  width   字符最大宽度
         * @returns  字体大小
        */
		virtual FCSize textSize(String strText, FCFont *font, int width);
		/**
         * 获取文字大小
         * @param  text   文字
         * @param  font   字体
		 * @param  width   字符最大宽度
         * @returns  字体大小
        */
		virtual FCSizeF textSizeF(String strText, FCFont *font);
	    /**
         * 获取文字大小
         * @param  text   文字
         * @param  font   字体
		 * @param  width   字符最大宽度
         * @returns  字体大小
        */
		virtual FCSizeF textSizeF(String strText, FCFont *font, int width);
		/*
        * 水平位移
        * @param x 横向距离
        * @param y 纵向距离
        */
        virtual void translate(float x, float y);
	};
}

#endif